//
//  XBWebView.m
//  TLKeepCredit
//
//  Created by mc on 2017/10/17.
//  Copyright © 2017年 mac. All rights reserved.
//

#import "XBWebView.h"

static void *WBContext = &WBContext;

@implementation XBWebView{
    WKWebView *_wkWebView;
    UIWebView *_uiWebView;
    UIProgressView *_progressView;
    NSTimer *_fakeProgressTimer;
    BOOL _uiWebViewIsLoading;
    NSURL *_uiWebViewCurrentURL;
}

+ (XBWebView *)webView
{
    XBWebView *webView = [XBWebView webViewWithConfiguration:nil];
    return webView;
}

+ (XBWebView *)webViewWithConfiguration:(WKWebViewConfiguration *)configuration {
    XBWebView *webView = [[XBWebView alloc] initWithConfiguration:configuration];
    return webView;
}

#pragma mark - 初始化
#pragma mark --- XIB
- (void)awakeFromNib
{
    if(self) {
        if([WKWebView class]) {
            _wkWebView = [[WKWebView alloc] init];
        }
        else {
            _uiWebView = [[UIWebView alloc] init];
        }
        [self initWebView];
    }
}

#pragma mark --- 代码初始化
- (id)init {
    return [self initWithConfiguration:nil];
}

- (id)initWithConfiguration:(WKWebViewConfiguration *)configuration {
    self = [super init];
    if(self) {
        if([WKWebView class]) {
            if(configuration) {
                _wkWebView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
            }
            else {
                _wkWebView = [[WKWebView alloc] init];
            }
        }
        else {
            _uiWebView = [[UIWebView alloc] init];
        }
        
        [self initWebView];
    }
    return self;
}

- (void)initWebView
{
    if(_wkWebView) {
        [_wkWebView setFrame:self.bounds];
        [_wkWebView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
        [_wkWebView setNavigationDelegate:self];
        [_wkWebView setMultipleTouchEnabled:YES];
        [_wkWebView setAutoresizesSubviews:YES];
        [_wkWebView.scrollView setAlwaysBounceVertical:YES];
        [self addSubview:_wkWebView];
        
        [_wkWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:WBContext];
    }
    else if(_uiWebView) {
        [_uiWebView setFrame:self.bounds];
        [_uiWebView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
        [_uiWebView setDelegate:self];
        [_uiWebView setMultipleTouchEnabled:YES];
        [_uiWebView setAutoresizesSubviews:YES];
        [_uiWebView setScalesPageToFit:YES];
        [_uiWebView.scrollView setAlwaysBounceVertical:YES];
        [self addSubview:_uiWebView];
    }
    
    _progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
    [_progressView setTrackTintColor:[UIColor colorWithWhite:1.0f alpha:0.0f]];
    [_progressView setFrame:CGRectMake(0, 0, SCREEN_WIDTH, _progressView.frame.size.height)];
    //    [_progressView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin];
    [self addSubview:_progressView];
}

#pragma mark - Public Interface
#pragma mark ---加载URL（NSURL类型）
- (void)loadURL:(NSURL *)url withTimeoutInterval:(NSTimeInterval)timeoutInterval
{
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeoutInterval];
    if(_wkWebView) {
        [_wkWebView loadRequest:request];
    }
    else if(_uiWebView) {
        [_uiWebView loadRequest:request];
    }
}

#pragma mark ---加载URL（NSString类型）
- (void)loadURLString:(NSString *)URLString withTimeoutInterval:(NSTimeInterval)timeoutInterval
{
    NSURL *url = [NSURL URLWithString:URLString];
    if(!url){
        return;
    }
    
    [self loadURL:url withTimeoutInterval:timeoutInterval];
}
#pragma mark ---加载HTML（NSString类型）
- (void)loadHTMLString:(NSString *)htmlString baseURL:(NSURL *)baseURL {
    if(_wkWebView) {
        [_wkWebView loadHTMLString:htmlString baseURL:baseURL];
    }
    else if(_uiWebView) {
        [_uiWebView loadHTMLString:htmlString baseURL:baseURL];
    }
}


#pragma mark ---设置是否显示进度条
- (void)setHiddenProgress:(BOOL)hiddenProgress
{
    _hiddenProgress = hiddenProgress;
    _progressView.hidden = hiddenProgress;
}

#pragma mark ---设置进度条颜色
- (void)setProgressTintColor:(UIColor *)progressTintColor
{
    _progressTintColor = progressTintColor;
    [_progressView setTintColor:progressTintColor];
}

#pragma mark - UIWebViewDelegate 委托
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if(webView == _uiWebView) {
        if ([self.delegate respondsToSelector:@selector(wbWebView:shouldStartLoadWithRequest:)]) {
            if (![self.delegate wbWebView:self shouldStartLoadWithRequest:request]) {
                return NO;
            }
        }
        
        _uiWebViewCurrentURL = request.URL;
        _uiWebViewIsLoading = YES;
        
        [self fakeProgressViewStartLoading];
        
        if([self.delegate respondsToSelector:@selector(wbWebView:didStartLoadingURL:)]) {
            [self.delegate wbWebView:self didStartLoadingURL:request.URL];
        }
    }
    return YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    if(webView == _uiWebView) {
        if(!_uiWebView.isLoading) {
            _uiWebViewIsLoading = NO;
            
            [self fakeProgressBarStopLoading];
            
            [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];
            [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
        
        if([self.delegate respondsToSelector:@selector(wbWebView:didFinishLoadingURL:)]) {
            [self.delegate wbWebView:self didFinishLoadingURL:_uiWebView.request.URL];
        }
    }
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    if(webView == _uiWebView) {
        if(!_uiWebView.isLoading) {
            _uiWebViewIsLoading = NO;
            
            [self fakeProgressBarStopLoading];
        }
        if([self.delegate respondsToSelector:@selector(wbWebView:didFailToLoadURL:error:)]) {
            [self.delegate wbWebView:self didFailToLoadURL:_uiWebView.request.URL error:error];
        }
    }
}

#pragma mark - WKNavigationDelegate 委托
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if (webView == _wkWebView) {
        if ([self.delegate respondsToSelector:@selector(wbWebView:shouldStartLoadWithRequest:)]) {
            if (![self.delegate wbWebView:self shouldStartLoadWithRequest:navigationAction.request]) {
                decisionHandler(WKNavigationActionPolicyCancel);
            }else{
                decisionHandler(WKNavigationActionPolicyAllow);
            }
        }else{
            decisionHandler(WKNavigationActionPolicyAllow);
        }
    }
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    if(webView == _wkWebView) {
        if([self.delegate respondsToSelector:@selector(wbWebView:didStartLoadingURL:)]) {
            [self.delegate wbWebView:self didStartLoadingURL:_wkWebView.URL];
        }
    }
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    if(webView == _wkWebView) {
        if([self.delegate respondsToSelector:@selector(wbWebView:didFinishLoadingURL:)]) {
            [self.delegate wbWebView:self didFinishLoadingURL:_wkWebView.URL];
        }
    }
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation
      withError:(NSError *)error
{
    if(webView == _wkWebView) {
        if([self.delegate respondsToSelector:@selector(wbWebView:didFailToLoadURL:error:)]) {
            [self.delegate wbWebView:self didFailToLoadURL:_wkWebView.URL error:error];
        }
    }
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation
      withError:(NSError *)error
{
    if(webView == _wkWebView) {
        if([self.delegate respondsToSelector:@selector(wbWebView:didFailToLoadURL:error:)]) {
            [self.delegate wbWebView:self didFailToLoadURL:_wkWebView.URL error:error];
        }
    }
}

#pragma mark - 进度条控制 KVO (WKWebView)
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == _wkWebView) {
        [_progressView setAlpha:1.0f];
        
        BOOL animated = _wkWebView.estimatedProgress > _progressView.progress;
        [_progressView setProgress:_wkWebView.estimatedProgress animated:animated];
        
        // Once complete, fade out UIProgressView
        if(_wkWebView.estimatedProgress >= 1.0f) {
            [UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                [_progressView setAlpha:0.0f];
            } completion:^(BOOL finished) {
                [_progressView setProgress:0.0f animated:NO];
            }];
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

#pragma mark - 进度条控制 (UIWebView)
- (void)fakeProgressViewStartLoading
{
    [_progressView setProgress:0.0f animated:NO];
    [_progressView setAlpha:1.0f];
    
    if(!_fakeProgressTimer) {
        _fakeProgressTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(fakeProgressTimerDidFire:) userInfo:nil repeats:YES];
    }
}

- (void)fakeProgressBarStopLoading
{
    if(_fakeProgressTimer) {
        [_fakeProgressTimer invalidate];
    }
    
    if(_progressView) {
        [_progressView setProgress:1.0f animated:YES];
        [UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
            [_progressView setAlpha:0.0f];
        } completion:^(BOOL finished) {
            [_progressView setProgress:0.0f animated:NO];
        }];
    }
}

- (void)fakeProgressTimerDidFire:(id)sender
{
    CGFloat increment = 0.005/(_progressView.progress + 0.2);
    if([_uiWebView isLoading]) {
        CGFloat progress = (_progressView.progress < 0.75f) ? _progressView.progress + increment : _progressView.progress + 0.0005;
        if(_progressView.progress < 0.95) {
            [_progressView setProgress:progress animated:YES];
        }
    }
}

- (void)dealloc
{
    [_uiWebView setDelegate:nil];
    
    [_wkWebView setNavigationDelegate:nil];
    [_wkWebView setUIDelegate:nil];
    [_wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
}
@end
